package com.springboot.config.log;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.RequestFacade;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: zyj
 * @create: 2020-08-24 16:09
 **/
@Aspect
@Component
@Slf4j
public class RequestControllerLog {

    @Resource
    private WriteLog writeLog;

    @Pointcut("@within(com.springboot.config.log.SpringBootRequestLog)")
    public void methodArgs() {
    }

    @Around("methodArgs()")
    public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object  result = joinPoint.proceed();
        HttpServletRequest httpServletRequest = null;

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if(null != requestAttributes){
            httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
        }

        /**日志打印*/
        long end = System.currentTimeMillis();
        Map<String, Object> param = new HashMap<>();

        try {
            if(null != httpServletRequest){
                // ip地址
                param.put("ipAddr" , getRemoteHost(httpServletRequest));
                log.info("request:{}", httpServletRequest);
                String requestUrl = null;
                if(httpServletRequest instanceof RequestFacade){
                    RequestFacade requestFacade = (RequestFacade) httpServletRequest;
                    requestUrl = requestFacade.getServletPath();
                }else {
                    requestUrl = String.valueOf(httpServletRequest.getRequestURL());
                }
                // 请求路径
                param.put("requestUrl" , requestUrl);
                // 请求方法
                param.put("method" , httpServletRequest.getMethod());
            }
        }catch (Exception e){
           log.error("RequestControllerLog error" , e);
        }


        writeLog.writeOut(joinPoint, result, param, end-start);

        return result;
    }
    /**
     * 获取目标主机的ip
     * @param request
     * @return
     */
    private String getRemoteHost(HttpServletRequest request) {
        if(null == request){
            return null;
        }

        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if(StringUtils.isEmpty(ip)){
            return "未找到ip";
        }
        return ip.contains("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

}
